package ClassData;

import java.nio.ByteBuffer;

import ClassData.Visitor.IVisitor;
import ClassData.Visitor.IVisitorElement;

public class AttributeInfo implements IVisitorElement {

	short attribute_name_index;
	byte  [] AttributeData;

	public AttributeInfo() {
		
	}

	public AttributeInfo(short newNameIndex,byte [] newData) {
		attribute_name_index=newNameIndex;
		AttributeData=newData;
	}
/*
 *     attribute_info {
    	u2 attribute_name_index;
    	u4 attribute_length;
    	u1 info[attribute_length];
    }
	
 */


public static AttributeInfo parseAttribute(ByteBuffer dataBuffer, ConstantPool constantPool)
{
	int AttributeDataLenght;
	short AttributeIndex;
	
	String AttributeName;
	
	AttributeIndex=dataBuffer.getShort();
	
	AttributeDataLenght=dataBuffer.getInt();
	
	ConstantPoolUtf8_Info myAttributeName;
	myAttributeName=(ConstantPoolUtf8_Info) constantPool.get(AttributeIndex);
	AttributeName=myAttributeName.getString();
	
	
	if (AttributeName.equals("ConstantValue")) {
		AttributeInfo_ConstantValue  myConstantValueAttribute;
		myConstantValueAttribute= new AttributeInfo_ConstantValue(dataBuffer.getShort());
		
		return(myConstantValueAttribute);
	}
	else if (AttributeName.equals("Code")) {
		return(new AttributeInfo_Code(dataBuffer,constantPool));
	}
	else if (AttributeName.equals("Exceptions")) {
		return(new AttributeInfo_Exceptions(dataBuffer));
	}
	else if (AttributeName.equals("InnerClasses")) {
		byte[] AttributeData;
		AttributeData = new byte [AttributeDataLenght];
		dataBuffer.get(AttributeData, 0, AttributeData.length);
/*
 *     InnerClasses_attribute {
    	u2 attribute_name_index;
    	u4 attribute_length;
    	u2 number_of_classes;
    	{  u2 inner_class_info_index;	     
    	   u2 outer_class_info_index;	     
    	   u2 inner_name_index;	     
    	   u2 inner_class_access_flags;	     
    	} classes[number_of_classes];
    }

 */
	}
	else if (AttributeName.equals("Synthetic")) {
		return(new AttributeInfo_Synthetic());
	}
	else if (AttributeName.equals("SourceFile")) {
		AttributeInfo_SourceFile  mySourceFileAttribute;
		mySourceFileAttribute= new AttributeInfo_SourceFile(dataBuffer.getShort());
		return(mySourceFileAttribute);
	}
	else if (AttributeName.equals("LineNumberTable")) {
		byte[] AttributeData;
		AttributeData = new byte [AttributeDataLenght];
		dataBuffer.get(AttributeData, 0, AttributeData.length);
/*
 *     LineNumberTable_attribute {
    	u2 attribute_name_index;
    	u4 attribute_length;
    	u2 line_number_table_length;
    	{  u2 start_pc;	     
    	   u2 line_number;	     
    	} line_number_table[line_number_table_length];
    }

 */

	}
	else if (AttributeName.equals("LocalVariableTable")) {
		byte[] AttributeData;
		AttributeData = new byte [AttributeDataLenght];
		dataBuffer.get(AttributeData, 0, AttributeData.length);
/*
 *     LocalVariableTable_attribute {
    	u2 attribute_name_index;
    	u4 attribute_length;
    	u2 local_variable_table_length;
    	{  u2 start_pc;
    	    u2 length;
    	    u2 name_index;
    	    u2 descriptor_index;
    	    u2 index;
    	} local_variable_table[local_variable_table_length];
    }	

 */
	}
	else if (AttributeName.equals("Deprecated")) {
		return(new AttributeInfo_Deprecated());
	}
	else if (AttributeName.equals("StackMapTable")) {
		byte[] AttributeData;
		AttributeData = new byte [AttributeDataLenght];
		dataBuffer.get(AttributeData, 0, AttributeData.length);
	} 
	else if (AttributeName.equals("Signature")) {
		return(new AttributeInfo_Signature(dataBuffer.getShort()));
	}
	else {
		byte[] AttributeData;
		AttributeData = new byte [AttributeDataLenght];
		dataBuffer.get(AttributeData, 0, AttributeData.length);
		//TODO Exception
		System.out.println("Unknown Attribute !!!!! -> " + AttributeName);
	}
	
	//TODO Exception unknown Attribute;
	return(null);	
}

	@Override
	public void receive_Visitor(IVisitor visitor) {
		visitor.visit_AttributeInfo(this);
	}

}
